// Copyright©,2020-2025
// Author: caocheng
// Version: 1.0.0
// Date: 2021/3/9 13:46
// Description：
package SummerCore

import (
	"errors"
	"reflect"

	"gitee.com/chrischo/go-summer/summer/summer-logger"
)

// Runner 立即执行器
type Runner struct {
	runnable
	ctx *defaultApplicationContext
}

// newRunner Runner 的构造函数，fn 不能返回 error 以外的其他值
func newRunner(ctx *defaultApplicationContext, fn interface{}, tags []string) *Runner {

	fnType := reflect.TypeOf(fn)
	if fnType.Kind() != reflect.Func {
		panic(errors.New("fn must be a func"))
	}

	return &Runner{
		ctx: ctx,
		runnable: runnable{
			fn:        fn,
			stringArg: newFnStringBindingArg(fnType, false, tags),
		},
	}
}

// Options 设置 Option 模式函数的参数绑定
func (r *Runner) Options(options ...*optionArg) *Runner {
	r.optionArg = &fnOptionBindingArg{options}
	return r
}

// When 参数为 true 时执行器立即执行
func (r *Runner) When(ok bool) error {
	if ok {
		return r.run()
	}
	return nil
}

// On Condition 判断结果为 true 时执行器立即执行
func (r *Runner) On(cond Condition) error {
	if cond.Matches(r.ctx) {
		return r.run()
	}
	return nil
}

func (r *Runner) run() error {
	defer func() { // 捕获自动注入过程中的异常，打印错误日志然后重新抛出
		if err := recover(); err != nil {
			SummerLogger.Errorf("%v ↩\n%s", err, err)
			panic(err)
		}
	}()

	return r.runnable.run(r.ctx)
}
